import utils from "..";
import StorageCompatible from "./StorageCompatible";

/** 存储方式 */
enum cacheMode {
  /** 先进先出 */
  fifo,
  /** 后进先出 */
  lifo
}

interface IProp {
  mode?: cacheMode,
}

const storageInfo: {
  /** 缓存keys */
  keys: string[];
  /** 缓存区总size */
  limitSize: number;
  /** 缓存区已使用size */
  currentSize: number;
} = {
  limitSize: 0,
  currentSize: 0,
  keys: []
}

export default class StorageUtilClass extends StorageCompatible {
  /** 存储方式 */
  protected mode!: cacheMode;

  constructor(prop?: IProp) {
    super()

    const info = this.getStorageInfo()

    this.mode                = prop?.mode || cacheMode.fifo
    storageInfo.keys         = info.keys
    storageInfo.limitSize    = info.limitSize
    storageInfo.currentSize  = info.currentSize
  }

  /** 获取sotrage
   * @param key key
   */
  public getItem(key: string): any {
    const cache = this.queryStorageByKey(key) || {t: 0, v: undefined}

    if (cache.t === -1) {
      return cache.v
    } else if (cache.t < Date.now()) {
      return undefined
    } else return cache.v
  }

  /** 存储storage
   * @param key key
   * @param val val
   * @param overtime 过期时间，单位：天，-1为不过期
   */
  public setItem(key: string, val: any, overtime: number = 1) {
    if (utils.typeof(val, 'function')) {
      throw Error('无法对函数进行存储')
    } else {
      const tmp = Date.now()
      const unit = 1000 * 60 * 60 * 24
      const t = overtime === -1 ? -1 : tmp + unit * overtime
      const data = {t, v: val}
      const size = JSON.stringify(data).length

      // if (size > storageInfo.limitSize) {
      //   throw Error('数据溢出，无法进行存储，请对数据进行切割！')
      // }

      try {
        this.saveStorage(key, data)

        storageInfo.currentSize += size
        storageInfo.keys.push(key)
      } catch (error) {
        // let delKey = ''

        // if (this.mode === cacheMode.fifo) {
        //   delKey = storageInfo.keys.shift() || ''
        // } else if (this.mode === cacheMode.lifo) {
        //   delKey = storageInfo.keys.pop() || ''
        // }

        // if (delKey) {
        //   this.deleteStorageByKey(delKey)
        //   this.setItem(key, val, overtime)
        // } else {
          throw Error('数据溢出，无法进行存储，请对数据进行切割！')
        // }
      }
    }
  }

  /** 删除Storage */
  public delItem(key: string) {
    const data = this.getItem(key)
    const size = data ? JSON.stringify(data).length : 0

    this.deleteStorageByKey(key)

    storageInfo.currentSize -= size
    storageInfo.keys = storageInfo.keys.filter(k => k !== key)
  }

  /** 清空Storage */
  public clear() {
    storageInfo.keys = []
    storageInfo.currentSize = 0

    this.clearStorage()
  }
}